﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using MotoGame.Core;

namespace MotoGame.Estados.Jogo
{
    class Jogo : EstadoBase
    {
        SpriteFont arial;
        int time;

        Moto moto1;
        Moto moto2;

        IList<Sprite> sprites;
        IList<Message> messages;

        MotoGame.Core.KeyInput input;
        CollisionDetector collisionDetector;

        Message score;
        Message clock;
        Message updates;
        
        public Jogo(MainGame game) :base(game)
        {
            sprites = new List<Sprite>();
            messages = new List<Message>();

            moto1 = new Moto(Game.Content, Game.Window, new Vector2(200, 300));
            moto2 = new Moto(Game.Content, Game.Window, new Vector2(400, 400));

            sprites.Add(moto1);
            sprites.Add(moto2);

            arial = Game.Content.Load<SpriteFont>("arial");

            score = new Message(game);
            score.Position = new Vector2(10, 10);

            clock = new Message(game);
            clock.Position = new Vector2(10, 30);

            updates = new Message(game);
            updates.Position = new Vector2(10, 50);

            messages.Add(score);
            messages.Add(clock);
            messages.Add(updates);

            input = new Core.KeyInput();
            input.Mapping[Keys.Escape] = () => { Game.Exit(); };
            input.Mapping[Keys.F11] = () => { Game.Graphics.ToggleFullScreen(); };
            input.Mapping[Keys.M] = () => { MediaPlayer.IsMuted = !MediaPlayer.IsMuted; };
            input.Mapping[Keys.Subtract] = () => { MediaPlayer.Volume -= 0.2f; };
            input.Mapping[Keys.Add] = () => { MediaPlayer.Volume += 0.2f; };

            input.Mapping[Keys.Up] = () => { moto1.Move(Moto.Direction.Up); };
            input.Mapping[Keys.Down] = () => { moto1.Move(Moto.Direction.Down); };
            input.Mapping[Keys.Left] = () => { moto1.Move(Moto.Direction.Left); };
            input.Mapping[Keys.Right] = () => { moto1.Move(Moto.Direction.Right); };

            input.Mapping[Keys.W] = () => { moto2.Move(Moto.Direction.Up); };
            input.Mapping[Keys.S] = () => { moto2.Move(Moto.Direction.Down); };
            input.Mapping[Keys.A] = () => { moto2.Move(Moto.Direction.Left); };
            input.Mapping[Keys.D] = () => { moto2.Move(Moto.Direction.Right); };

            collisionDetector = new CollisionDetector();
            collisionDetector.Sprites = sprites;
            collisionDetector.OnHit += (sender, args) => 
            {
                if ((args.First == moto1 && args.Last == moto2)
                || (args.First == moto2 && args.Last == moto1))
                {
                    sprites.Remove(moto2);
                }
            };
            collisionDetector.OnHit += (sender, args) =>
            {
                updates.Text = "Colisão: " + args.First + " e " + args.Last;
            };
            
        }

        public override void Start() {
            time = 0;
        }

        public override void Update(GameTime gameTime)
        {
            time += gameTime.ElapsedGameTime.Milliseconds;

            input.Update(gameTime);
            collisionDetector.Update(gameTime);
            updates.Update(gameTime);

            foreach (var sprite in sprites)
            {
                sprite.Update(gameTime);
            }

            foreach (var message in messages)
            {
                message.Update(gameTime);
            }
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            score.Text = "Pontos: 0";
            clock.Text = "Tempo (ms): " + time;

            
            foreach (var sprite in sprites)
            {
                sprite.Draw(gameTime, spriteBatch);
            }

            foreach (var message in messages)
            {
                message.Draw(gameTime, spriteBatch);
            }
        }

        public override void Terminate() {}
    }
}
